# 引入合适的库
import matplotlib.pyplot as plt
import cv2 as cv
import numpy as np

img = cv.imread('x_ray.jpg', 0)  # 读取x_ray.jpg灰度图

######################## 1.极小极大值归一 ###########################

img_max = img.max()  # 获取图像最大值
img_min = img.min()  # 获取图像最小值
img_minmax_equalize_hist = (img - img_min) / (img_max - img_min)  # 极小极大值归一

######################## 2. 全局直方图均衡 ###########################
hist, _ = np.histogram(img.flatten(), 256, [0, 256])  # 获得img的直方图(分256个区间)
cdf = hist.cumsum()  # 获得hist对应的累积直方图，cdf是cumulative density function 是 cumulative frequency histogram的另一个常见名称
cdf = (cdf - cdf.min()) / (cdf.max() - cdf.min())  # 把累积直方图进行极小极大值归一获得累积频率直方图
img_equalize_hist = cdf[img]  # 通过累积频率直方图对img进行全局直方图均衡

######################## 3.log变换 ###########################
img = img.astype(np.float64)  # 需要把ubyte转成浮点数np.float类型以便进行log操作
c = 255 / np.log(img.max() + 1)  # 得到c
img_log = c * (np.log(img + 1))  # log变换

fg, ax = plt.subplots(2, 4, figsize=(16, 4))
# 用完整的数据范围打印图像及其直方图
ax[0, 0].imshow(img, cmap='gray', vmin=0, vmax=255)
ax[0, 0].set_title('original')
ax[1, 0].hist(img.ravel(), bins=256, range=[0, 255])
# 最小最大值归一
ax[0, 1].imshow(img_minmax_equalize_hist, cmap='gray', vmin=0, vmax=1)
ax[0, 1].set_title('min-max normalized image')
ax[1, 1].hist(img_minmax_equalize_hist.ravel(), bins=256, range=[0, 1])
# 全局直返图均衡
ax[0, 2].imshow(img_equalize_hist, cmap='gray')
ax[0, 2].set_title('global equalization')
ax[1, 2].hist(img_equalize_hist.ravel(), bins=256)
# 对数变换
ax[0, 3].imshow(img_log, cmap='gray')
ax[0, 3].set_title('log')
ax[1, 3].hist(img_log.ravel(), bins=256)

plt.tight_layout()
plt.savefig("out.png")
plt.show()
